#include "Embedded/EmIntergrid.h"

template <int Dim>
void EmIntergrid<Dim>::restrictResidual(const Tensor<Real, Dim> &fineData, Tensor<Real, Dim> &coarseData) const
{
  const auto &coarseLabels = coarseEmGrid.nodeLabels;
  const auto &fineLabels = fineEmGrid.nodeLabels;
  ddfor(coarseEmGrid, [&](const iVec &idx) {
    if(coarseLabels(idx) < 0) {
      coarseData(idx) = 0.0;
      return;
    }
    Real r = 0.0;
    int s = 0;
    ddfor(Box<Dim>(0, 1), [&](const iVec &delta) {
      if(fineLabels(idx * 2 + delta) >= 0) {
        r += fineData(idx * 2 + delta);
        ++s;
      }
    }, false);
    assert(s > 0);
    coarseData(idx) = (s > 0) ? (r/s) : (0.0);
  });
}

template <int Dim>
void EmIntergrid<Dim>::incrementalProlong(const Tensor<Real, Dim> &coarseData, Tensor<Real, Dim> &fineData) const
{
  const auto &coarseLabels = coarseEmGrid.nodeLabels;
  ddfor(fineEmGrid, [&](const iVec &idx) {
    if(coarseLabels(idx / 2) >= 0)
      fineData(idx) += coarseData(idx / 2);
  });
}

//============================================================
template class EmIntergrid<SpaceDim>;
